/* eslint-disable */
/**
 * 事件发射器类，用于管理事件和事件处理函数。
 */
class eventEmitter {
  /**
   * @param {Object} list - 存储事件和对应的处理函数列表。
   */
  private list: { [eventName: string]: Function[] }
  constructor() {
    this.list = {}
  }
  /**
   * 注册一个事件处理函数。
   * @param {string} eventName 要监听的事件名称。
   * @param {Function | undefined} fn 事件处理函数，默认为空函数。
   * @returns {eventEmitter} 返回事件发射器实例，支持链式调用。
   */
  on(eventName: string, fn?: Function): eventEmitter {
    if (!(typeof fn === 'function')) {
      return this
    }
    ;(this.list[eventName] || (this.list[eventName] = [])).push(fn as Function)
    return this
  }
  /**
   * 注册一个只触发一次的事件处理函数。
   * @param {string} eventName 要监听的事件名称。
   * @param {Function | undefined} fn 事件处理函数。
   * @returns {eventEmitter} 返回事件发射器实例，支持链式调用。
   */
  once(eventName: string, fn?: Function): eventEmitter {
    const _this = this
    if (!(typeof fn === 'function')) return _this
    /**
     * 执行它的时候就可以直接卸了 args为emit时第二个参数传递进来的
     */
    function _tempOn(...args: any[]) {
      _this.off(eventName, _tempOn)
      fn!.apply(_this, args)
    }
    _tempOn.fn = fn // 暂时记录这个fn，监听一次，被发布(emit)一次后，需要执行卸载的函数
    this.on(eventName, _tempOn)
    return _this
  }
  /**
   * 移除一个事件处理函数，或者移除指定事件名下的所有处理函数。
   * @param {string} eventName 要移除处理函数的事件名称。
   * @param {function | undefined} fn 要移除的具体事件处理函数，不传则移除所有处理函数。
   * @returns {eventEmitter} 返回事件发射器实例，支持链式调用。
   */
  off(eventName: string, fn?: Function): eventEmitter {
    const _this = this
    const fns = this.list[eventName]
    // 如果缓存列表中没有相应的 fns，直接跳过
    if (!fns) return _this
    if (!fn) {
      // 如果没有传 fn 的话，就会将 eventName 值对应缓存列表中的 fn(事件处理函数们) 都清空
      fns && (fns.length = 0)
      return _this
    }

    for (let i = 0; i < fns.length; i++) {
      const curFn = fns[i]
      // 如果缓存列表中的 fn(事件处理函数) 和 传入的 fn 相等，就删除这个 fn 或者是 once 时_tempOn上存的fn (ps情况：当on和once时，fn和_tempOn上的fn是注册同一个函数时once注册的是_tempOn ，而on注册的是fn,互不影响)
      if (curFn === fn || (curFn as any).fn === fn) {
        fns.splice(i, 1)
        i--
        // !指针永远不应该小于 0，因为只有一个的时候 i为-1的话 curFn 为undefined
        if (i < 0) i = 0
      }
    }

    return _this
  }

  /**
   * 触发一个事件，执行对应的事件处理函数 = 执行（发布）。
   * @param event 要触发的事件名称。
   * @param args 传递给事件处理函数的参数。
   * @returns 返回事件发射器实例，支持链式调用。
   */
  emit(eventName: string, ...args: any[]) {
    const _this = this
    if (typeof eventName !== 'string') return _this
    const fns = this.list[eventName]
    if (!fns || fns.length === 0) return _this

    for (const fn of fns) {
      fn.apply(_this, args)
    }
    return _this
  }
}

export default eventEmitter
